#pragma warning(disable: 4005)

#include "Win32XmlHelpers.h"
#include "NeroGame\NGame.h"
#include "NeroGame\NXmlParseMaster.h"
#include "NeroGame\NFactory.h"
//Resources
#include "DirectX\Shader.h"
#include "DirectX\Material.h"
#include "DirectX\Model.h"
#include "DirectX\Texture.h"
//Managers
#include "DirectX\ShaderResourceManager.h"
#include "DirectX\MaterialResourceManager.h"
#include "DirectX\ModelResourceManager.h"
#include "DirectX\TextureResourceManager.h"

using namespace NXML;
using namespace Graphics;

bool NXmlAnimationHelper::StartElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(),"Sprite"))
	{
		//NXML::NXmlParseMaster::NXmlSharedData* sharedData = mXmlMaster->GetSharedData();

		std::string entityName = element->Attribute("entity");
		//sharedData->CurrentScope = GetGame()->GetEntity(entityName);
		return true;
	}
	else if(!strcmp(element->Value(),"Animation"))
	{
		/*NXML::NXmlParseMaster::NXmlSharedData* sharedData = mXmlMaster->GetSharedData();
		Win32SpriteComponent::Animation newAnimation;
		std::string name = element->Attribute("name");
		newAnimation.Name = name;

		std::string isLooping = element->Attribute("loop");
		if(isLooping == "true")
		{
			newAnimation.IsLooping = true;
		}
		else
		{
			newAnimation.IsLooping = false;
		}

		if(sharedData->CurrentScope != NULL)
		{
			Engine::NEntity* currentEntity = sharedData->CurrentScope->As<Engine::NEntity>();
			if(currentEntity)
			{
				newAnimation.CurrentFrame = 0;
				Win32SpriteComponent* sprite = (Win32SpriteComponent*)currentEntity->GetComponent("Win32SpriteComponent");
				if(sprite)
				{
					sprite->AddAnimation(newAnimation);
				}
			}
		}*/
		return true;
	}
	else if(!strcmp(element->Value(),"Frame"))
	{
		/*NXML::NXmlParseMaster::NXmlSharedData* sharedData = mXmlMaster->GetSharedData();
		Win32SpriteComponent::Frame newFrame;

		std::string X = element->Attribute("x");

		std::string Y = element->Attribute("y");

		std::string top = element->Attribute("top");
		newFrame.Top = atoi(top.c_str());

		std::string bottom = element->Attribute("bottom");
		newFrame.Bottom = atoi(bottom.c_str());

		std::string right = element->Attribute("right");
		newFrame.Right = atoi(right.c_str());

		std::string left = element->Attribute("left");
		newFrame.Left = atoi(left.c_str());
		
		if(sharedData->CurrentScope != NULL)
		{
			Engine::NEntity* currentEntity = sharedData->CurrentScope->As<Engine::NEntity>();
			if(currentEntity)
			{
				Win32SpriteComponent* sprite = (Win32SpriteComponent*)currentEntity->GetComponent("Win32SpriteComponent");
				if(sprite)
				{
					Win32SpriteComponent::Animation& aAnimation = sprite->GetAnimation(sprite->GetAnimations().size() - 1);
					aAnimation.Frames.push_back(newFrame);
					aAnimation.Period = aAnimation.Frames.size() * 60;
				}
			}
		}*/
		return true;
	}
	return false;
}

bool NXmlAnimationHelper::EndElementHandler(TiXmlElement* element)
{
	if( !strcmp(element->Value(),"Sprite")		||
		!strcmp(element->Value(),"Animation")	||
		!strcmp(element->Value(),"Frame"))
	{
		return true;
	}
	return false;
}

bool NXmlTextureHelper::StartElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(),"Texture"))
	{
		std::string instanceName = element->Attribute("instanceName");
		std::string filePath = element->Attribute("filePath");

		Graphics::TextureResourceManager::GetInstance()->Add(instanceName, filePath);

		Graphics::Texture* newTexture = Graphics::TextureResourceManager::GetInstance()->GetResource(instanceName);
		if(newTexture)
		{
			newTexture->Initialize();
		}
		return true;
	}
	return false;
}

bool NXmlTextureHelper::EndElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(),"Texture"))
	{

		return false;
	}
	return false;
}

bool NXmlMaterialHelper::StartElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(),"Material"))
	{
		std::string materialClass		= element->Attribute("class");
		std::string instanceName		= element->Attribute("instanceName");
		std::string shaderInstanceName	= element->Attribute("shader");
		
		Graphics::Material* newMaterial = Utility::NFactory<Graphics::Material>::Create(materialClass);
		if(newMaterial)
		{
			MaterialResourceManager::GetInstance()->Add(instanceName,newMaterial);
			Graphics::Shader* shader = ShaderResourceManager::GetInstance()->GetResource(shaderInstanceName);
			if(shader)
			{
				newMaterial->SetShader(shader);
			}
			else
			{
				//error
			}
			return true;
		}
	}
	return false;
}

bool NXmlMaterialHelper::EndElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(),"Material"))
	{
		return true;
	}
	return false;
}

bool NXmlShaderHelper::StartElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(),"Shader"))
	{
		//checking for valid attributes
		if(!element->Attribute("class"))
		{
			return true;
		}

		std::string shaderClass	= element->Attribute("class");
		std::string instanceName = element->Attribute("instanceName");
#ifdef DX_11
		ShaderResourceManager::GetInstance()->Add(instanceName,"");
#elif defined(DX_9)
		std::string filePath = element->Attribute("filePath");
		ShaderResourceManager::GetInstance()->Add(instanceName,filePath);
#endif
		Shader* newShader = ShaderResourceManager::GetInstance()->GetResource(instanceName);

		if(newShader)
		{
			newShader->Initialize();
		}
		return true;
	}
	return false;
}

bool NXmlShaderHelper::EndElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(),"Shader"))
	{
		return true;
	}
	return false;
}

bool NXmlModelHelper::StartElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(),"Model"))
	{
		std::string instanceName = element->Attribute("instanceName");
		std::string filePath = element->Attribute("filePath");

		Graphics::Model* newModel = MY_NEW(Memory::HID_Rendering,"Model")Model(instanceName,filePath);
		if(newModel)
		{
			newModel->Initialize();
			ModelResourceManager::GetInstance()->Add(instanceName, newModel);
		}
		return true;
	}
	return false;
}

bool NXmlModelHelper::EndElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(),"Model"))
	{
		return true;
	}
	return false;
}

bool NXmlPlatformHelper::StartElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(), "Platform"))
	{		
		//if device matches define contine loading xml		
#ifdef DX_11
		if(!strcmp(element->Attribute("device"),"DX_11"))
		{	
#elif defined(DX_9)
		if(!strcmp(element->Attribute("device"),"DX_9"))
		{
#endif
			NXmlParseMaster::GetInstance()->GetSharedData()->SkipContainedData = false;
		}
		//if device does not match define skip contained xml
		else
		{
			NXmlParseMaster::GetInstance()->GetSharedData()->SkipContainedData = true;
		}
		return true;
	}
	return false;
}

bool NXmlPlatformHelper::EndElementHandler(TiXmlElement* element)
{
	if(!strcmp(element->Value(), "Platform"))
	{
		return true;
	}
	return false;
}